package nginx

import (
	"db-sharding/config"
	"db-sharding/system/log4go"
	"fmt"
	"github.com/tufanbarisyildirim/gonginx"
	"github.com/tufanbarisyildirim/gonginx/parser"
	"os"
	"os/exec"
	"strconv"
)

func ModifyProxyConfig(proxyPort int, host string) {
	path := config.GlobalCfg.Proxy.NginxConfPath
	//获取配置文件
	p, err := parser.NewParser(path)
	if err != nil {
		log4go.Warn(err)
	}

	conf := p.Parse()

	//修改代理配置
	modifyServer(conf, proxyPort, host)

	//写入磁盘文件
	writeConfig(conf, path)

	//刷新ng
	reloadNginx()

}

func reloadNginx() {
	command := config.GlobalCfg.Proxy.NginxReloadShellPath
	cmd := exec.Command("/bin/bash", "-c", command)

	output, err := cmd.Output()
	if err != nil {
		fmt.Printf("nginx刷新脚本执行失败:%s failed with error:%s", command, err.Error())
		return
	}
	fmt.Printf("nginx刷新脚本执行成功:%s finished with output:\n%s", command, string(output))
}

//新增一个代理，入参：ip:post，返回本地代理端口
func addServer(conf *gonginx.Config, proxyPort int, host string) {
	//记录下当前最大的端口号
	stream := conf.FindDirectives("stream")[0]
	servers := stream.GetBlock().FindDirectives("server")

	//IDirective

	newDirect := &gonginx.Directive{
		Block: &gonginx.Block{
			Directives: []gonginx.IDirective{
				&gonginx.Directive{
					Name:       "listen",
					Parameters: []string{strconv.Itoa(proxyPort)},
				},
				&gonginx.Directive{
					Name:       "proxy_connect_timeout",
					Parameters: []string{"10s"},
				},
				&gonginx.Directive{
					Name:       "proxy_timeout",
					Parameters: []string{"300s"},
				},
				&gonginx.Directive{
					Name:       "proxy_pass",
					Parameters: []string{host},
				},
			},
		},
		Name: "server",
	}

	newServer, _ := gonginx.NewServer(newDirect)

	servers = append(servers, newServer)

	switch v := stream.GetBlock().(type) {
	case *gonginx.Block:
		v.Directives = servers
	}
}

func writeConfig(conf *gonginx.Config, path string) {
	configContent := gonginx.DumpConfig(conf, gonginx.IndentedStyle)

	log4go.Info(configContent)

	dstFile, err := os.Create(path)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer dstFile.Close()

	dstFile.WriteString(configContent)
}

func modifyServer(conf *gonginx.Config, proxyPort int, host string) {
	port := strconv.Itoa(proxyPort)
	direct := conf.FindDirectives("stream")[0]
	servers := direct.GetBlock().FindDirectives("server")
	var index = -1
	for i, server := range servers {
		params := server.GetBlock()

		for _, directive := range params.GetDirectives() {
			if directive.GetName() == "listen" && directive.GetParameters()[0] == port {
				index = i
				break
			}
		}
	}
	if index > -1 {
		for _, directive := range servers[index].GetBlock().GetDirectives() {
			if directive.GetName() == "proxy_pass" {
				directive.GetParameters()[0] = host
			}
		}
	} else {
		log4go.Warn("修改失败，不存在端口号", proxyPort, "的代理配置，直接新增")
		addServer(conf, proxyPort, host)
	}
}
